﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace QAQ
{
    class GameCtrl
    {
        private MouseCtrl mMouseCtrl = null;
        private DxDeviceCtrl mDxDeviceCtrl = null;
      //  public JoyControl mJoyControl = null;
        private IntPtr mProcessHwnd;

        public enum act
        {
            NxtPage,
            PrePage,
            SlaveEnterPass,
            ReadyToGo,
            Exit,
            Enter,
            MouseGoAway,
            ChangeCompeteType,
            CreateRoom,
            LeaveRoom,
            GoCompete,
            ConfigRoom,
            PromptYes
        };

        private enum Type
        {
            keyboard,
            mouseMove,
            mouseClick
        };
        private struct funcDescribe
        {
            public Type type;
            public DxDeviceCtrl.DirectInputKbdKey KeybdInput;
            public VirtualKeys VirtualKeyInput;
            public Point point;
            public int delay;
        };

        private Dictionary<act, funcDescribe> mDictDescribes;
        //TODO:Add Resolution  arguement
        public GameCtrl()
        {
            mMouseCtrl = new MouseCtrl();
            //mJoyControl = new JoyControl();
            mDxDeviceCtrl = new DxDeviceCtrl();

            mDictDescribes = new Dictionary<act, funcDescribe>
            {
                {act.NxtPage, new funcDescribe()
                {
                    type=Type.mouseClick,
                    delay = 300,
                    point = new Point(886,166)
                } },
                {act.PrePage, new funcDescribe()
                {
                    type=Type.mouseClick,
                    delay = 300,
                    point = new Point(808,166)
                } },
                {act.SlaveEnterPass, new funcDescribe()
                {
                    type=Type.mouseClick,
                    delay = 33 ,
                    point = new Point(646, 406)
                } },
                {act.ReadyToGo, new funcDescribe()
                {
                    type=Type.keyboard,
                    KeybdInput = DxDeviceCtrl.DirectInputKbdKey.DIK_F9,
                    VirtualKeyInput = VirtualKeys.F9,
                    delay = 33 ,
                    //point = new Point(1185, 858)
                } },
                {act.Exit, new funcDescribe()
                {
                    type=Type.keyboard,
                    KeybdInput =  DxDeviceCtrl.DirectInputKbdKey.DIK_ESCAPE,
                    VirtualKeyInput = VirtualKeys.Escape,
                    delay = 33 ,
                    //point = new Point(646, 406)
                } },
                {act.Enter, new funcDescribe()
                {
                    type=Type.keyboard,
                    KeybdInput = DxDeviceCtrl.DirectInputKbdKey.DIK_RETURN,
                    VirtualKeyInput = VirtualKeys.Return,
                    delay = 33 ,
                    //point = new Point(634, 464)
                } },
                {act.MouseGoAway, new funcDescribe()
                {
                    type=Type.mouseMove,
                    //KeybdInput = JoyControl.KEY_ENTER,
                    point = new Point(688, 300),
                    delay = 33 
                } },
                {act.ChangeCompeteType,new funcDescribe()
                {
                    type=Type.mouseClick,
                    delay = 33,
                    point = new Point(1000, 256)
                } },
                {act.CreateRoom,new funcDescribe()
                {
                    type=Type.mouseClick,
                    delay = 33,
                    point = new Point(900, 566)
                } },
                {act.LeaveRoom,new funcDescribe()
                {
                    type=Type.mouseClick,
                    point = new Point(1310, 64),
                    delay = 33
                } },
                {act.GoCompete,new funcDescribe()
                {
                    type=Type.mouseClick,
                    point = new Point(213, 58),
                    delay = 33
                } },
                {act.ConfigRoom,new funcDescribe()
                {
                    type=Type.mouseClick,
                    point = new Point(716, 65),
                    delay = 33
                } },
                {act.PromptYes, new funcDescribe()
                {
                    type=Type.keyboard,
                    KeybdInput = DxDeviceCtrl.DirectInputKbdKey.DIK_Y,
                    VirtualKeyInput = VirtualKeys.Y,
                    delay = 33 ,
                    //point = new Point(1185, 858)
                } }
                

            };
        }

        public void SetProcesshandle(IntPtr ProcessHandle)
        {
            mProcessHwnd = ProcessHandle;
        }

        public void Action(act what)
        {
            funcDescribe thisfunc = mDictDescribes[what];

            switch (thisfunc.type)
            {
                case Type.keyboard:
                    //mJoyControl.Key(thisfunc.KeybdInput);
                    mDxDeviceCtrl.Send(thisfunc.KeybdInput);
                    RingPostM.RingPst(mProcessHwnd,thisfunc.VirtualKeyInput,RingPostM.RingPstType.press);
                    break;
                case Type.mouseClick:
                    mMouseCtrl.MoveRelatedToProcess(mProcessHwnd,
                        thisfunc.point.X, thisfunc.point.Y);
                    System.Threading.Thread.Sleep(thisfunc.delay);
                    mDxDeviceCtrl.Send(DxDeviceCtrl.dxMouseButton.Left);
                    System.Threading.Thread.Sleep(thisfunc.delay*2);
                    mMouseCtrl.Release();
                    break;
                case Type.mouseMove:
                    mMouseCtrl.MoveRelatedToProcess(mProcessHwnd,
                        thisfunc.point.X, thisfunc.point.Y);
                    System.Threading.Thread.Sleep(thisfunc.delay);
                    mMouseCtrl.Release();
                    break;
                default:
                    throw new Exception("Action Type didn't set!");
                    break;
            }
            System.Threading.Thread.Sleep(thisfunc.delay);
        }


        public void EnterRoom(int index)
        {
            mMouseCtrl.MoveRelatedToProcess(mProcessHwnd,
                ImgProc.mRoomListStartX[0] + ImgProc.mRoomListOffX[0, index] + ImgProc.mRoomListWidth[0],
                ImgProc.mRoomListStartY[0] + ImgProc.mRoomListOffY[0, index] + ImgProc.mRoomListHeight[0] / 2);
            System.Threading.Thread.Sleep(50);
            mDxDeviceCtrl.Send(DxDeviceCtrl.dxMouseButton.Left);
        }

        public void SetControlText(IntPtr which, string str)
        {
            User32.SendMessage(which, WMsg.WM_SETTEXT, 0, str);
        }

        public string GetControlText(IntPtr hWnd)
        {

            StringBuilder title = new StringBuilder();

            // Get the size of the string required to hold the window title. 
            int size = User32.SendMessage(hWnd, WMsg.WM_GETTEXTLENGTH, 0, string.Empty);

            // If the return is 0, there is no title. 
            if (size > 0)
            {
                title = new StringBuilder(size + 1);

                User32.SendMessage(hWnd, (uint)WMsg.WM_GETTEXT, title.Capacity, title);

            }
            return title.ToString();
        }
    }
}
